Skip to main content
  1. Blog/

Why I Self-Host (Almost) Everything at Home

·11 mins
“You built your own server just to turn on a light?” How a white-noise speaker turned into two machines running about twenty services, and why I’d do it again.

Yes. Though in fairness the light came second. The first thing was a speaker that played white noise so I could sleep. Two and a half years later there are two computers in my flat that never turn off, running about twenty services between them, and I can’t point to the moment it stopped being reasonable.

If I had to reduce the “why” to one word it would be control, with customisation as the same idea wearing a different hat. But that’s the tidy retrospective version. What actually happened is that I went down a rabbit hole one light bulb at a time and worked out the philosophy on the way down.

It started with white noise #

April 2022. I bought a Google Home speaker so I could ask it to play white noise before bed. That was the entire ambition.

Two weeks later I had a Yeelight smart bulb, an Aqara motion sensor and an Aqara M1S hub, because once you own a speaker that can do things you start wondering what else it could do. The bulb was so I could turn my light off without getting up. Then I wired it through IFTTT to solve an actual problem. I tend to work with my phone on silent and noise-cancelling headphones on to cut distractions, which is great until someone needs to reach me. So I set it up that if a friend sent me a WhatsApp message containing a specific keyword, my desk light would flash, and I’d know to check my phone. A friend standing outside could get my attention without me having to hear a thing.

That was when the automation bug bit properly. I was living somewhere with housemates who were relaxed about locking up, in a neighbourhood where that mattered, so I set up the motion sensor to ping my phone if anyone walked into my room while I was out, and got the lights switching themselves on and off as I came and went.

All of it worked. It just had one problem I couldn’t stop noticing.

My light bulb had a commute #

Every one of those devices did the same thing under the hood. When I asked my light to turn on, the request left my house, went to a server in Europe or China, got processed, and came back. My bedroom light was routing instructions halfway around the planet and back, from a house in South Africa, to flick on.

The delay was usually a second or two. That doesn’t sound like much written down. It is enormous when you are standing in a doorway waiting for it, every day, several times a day.

The deeper problem was that none of it was mine. My automations lived on other people’s servers, subject to their uptime, their pricing and their decision to sunset a product on a Tuesday. IFTTT could rate-limit me. A vendor could push bad firmware. If Yeelight’s cloud had an outage, my lights were just lights.

The fix was obvious once I’d framed it that way. If the brain of the smart home lived in the house, requests wouldn’t need a passport.

Enter the Raspberry Pi #

In late 2023 I bought a Raspberry Pi 5 with 8GB of RAM to run Home Assistant, which has been the centre of the whole setup ever since. Instead of a dozen vendor apps each talking to a dozen clouds, Home Assistant talks to everything locally and lets me stitch it together however I like. A Raspberry Pi Zero took on network-wide ad blocking with Pi-hole.

The thing that makes Home Assistant worth the effort is that your automations execute on your own hardware. When I tell a light to go red at midnight, that logic runs three metres from the bulb rather than three thousand kilometres away. The second-or-two delay disappeared and has never come back.

I also added a Sonoff Zigbee 3.0 stick, which let me talk to Zigbee sensors and bulbs directly through Zigbee2MQTT instead of going through the Aqara hub. One less vendor in the chain.

Going overboard with automations #

With a local brain in place and no cloud round trip to worry about, the cost of trying an idea dropped to almost nothing. A sample of what I ended up with:

  • Bedroom lights fade to a dim red late in the evening, and switch on and off with motion.
  • A sensor on the front door pushes a notification to my phone every time it opens.
  • A smart plug cuts power to my phone charger once the battery hits 85%.
  • The air purifier switches itself off when the room humidity drops too low.
  • The kettle starts boiling when my alarm goes off.
  • Every morning, five minutes before my phone alarm, my bedroom lights begin a slow fade up to full brightness, so I wake up to light instead of noise.

The networking rabbit hole #

Pi-hole was blocking ads nicely for the devices that cooperated. A good number didn’t. Some gadgets ship with hard-coded DNS servers, others quietly ignore what the router hands them, and any device that picks its own DNS walks straight past your filtering.

So I stopped asking devices to behave and started making them. I set up a custom OpenWRT router that transparently redirects DNS traffic back through Pi-hole whether a device likes it or not. DNS-over-HTTPS is the asterisk on that, since it can still slip through. The bigger payoff was that between OpenWRT’s firewall and VLANs and Pi-hole’s device groups, I could give different devices completely different treatment, both in what gets filtered and in what they’re allowed to reach. My laptop, my IoT junk and a guest’s phone can share the same Wi-Fi and be treated as three separate classes of citizen.

The last piece was getting back in from outside. I wanted to control things when away from home without exposing anything to the open internet, so I set up Tailscale, which puts all my devices on a private mesh network. My phone now thinks it’s at home wherever it is.

From smart home to home lab #

Nobody warns you about what happens next. Once you own a small computer that runs 24 hours a day, it stops looking like a smart home hub and starts looking like a server, and a server wants jobs.

So I gave it jobs. I built an ambient lighting setup with Hyperion, which drives LEDs behind the TV that mirror what’s on screen, and fell down a second rabbit hole into addressable LEDs with LedFX. I started running my own dockerised apps too: a YouTube summariser, and a crypto trading bot that messages me on Telegram whenever it buys or sells.

I briefly considered hosting this blog on the Pi. I decided against it, because a dynamic home IP makes serving a public site more trouble than it’s worth and Cloudflare Pages does it for free. But the fact that I seriously thought about it says something about how much the default had shifted. By that point, anything that could run at home, I wanted to run at home.

Outgrowing the Pi #

By early 2024 the Pi was struggling. The crypto bot was working it hard and Jellyfin wanted to transcode video, which is a lot to ask of a Raspberry Pi. So I added a mini PC.

That brought up the question every Linux tinkerer secretly enjoys agonising over, which is which distribution to use. I spent far longer on this than the decision warranted and landed on EndeavourOS, which gets you Arch Linux and its rolling releases without quite so much assembly required.

The mini PC took the heavy lifting: Jellyfin, media tooling, the crypto bot, file sync. The Pi kept doing what it’s good at, which is being the always-on, low-power nerve centre for the smart home. Both have been running continuously since.

What I run today #

Spread across the Pi, the mini PC, the Pi Zero and the router:

Category Service What it does Where
Smart home Home Assistant Automations, dashboards, device control Pi
Smart home Mosquitto (MQTT) Message broker my devices talk through Pi
Smart home Zigbee2MQTT Bridges Zigbee sensors and bulbs Pi
Lighting Hyperion Ambient glow behind the TV Pi
Networking Pi-hole Network-wide ad and tracker blocking Pi Zero
Networking AdGuard DNS filtering at the router OpenWRT router
Networking Tailscale Private mesh VPN Everywhere
Media Jellyfin Films, series, downloads Mini PC
Media MeTube / HandBrake Downloading and transcoding video Mini PC
Backups Duplicati Scheduled encrypted backups Both
Sync Syncthing Keeps files and my ebook library in sync Mini PC
Ops Homepage One dashboard linking every service Both
Ops Uptime Kuma Tells me when something falls over Pi
Dev code-server VS Code in a browser tab, from any device Both
Custom YouTube summariser An app I built to summarise videos Pi
Custom Crypto bot Trades and pings me on Telegram Mini PC

So why bother? #

If someone asked me to make the case, this is what I’d actually say, rather than the usual list.

The latency thing is the whole argument in miniature. A second and a half doesn’t show up in a spec sheet or a review, but it’s the difference between a light that responds and a light you wait for. Local execution fixed it permanently. It also means my automations keep working when the internet drops, which has happened more often than any of the hardware failing.

I can build things nobody sells. The kettle boiling when my alarm goes off, the charger cutting out at 85%, the five-minute sunrise: none of these exist as products. They exist because Home Assistant let me connect a sensor to a plug with a condition in between. Every off-the-shelf app does what its makers imagined, which is never quite what you want.

Nothing can be taken away from me. IFTTT changed its free tier. Vendors discontinue hubs. My setup can’t be repriced, sunset, or quietly filled with adverts, because it runs on hardware I own.

It taught me things I now use at work. This is the one that crept up on me. Docker, DNS, VLANs, firewalls, VPNs, working comfortably in a terminal: I learned all of it because something was broken at 1am and I wanted it fixed. That’s a much better teacher than a tutorial.

Privacy, as a side effect. It wasn’t my motive but it’s real. Fewer devices phone home, my media sits on disks I can hold, and my usage patterns aren’t being sold to anyone.

Any problems? #

Plenty, and the post would be dishonest without them.

Docker networking was the steepest wall. Getting containers to talk to each other, to the host and to the outside world took me longer than I’d like to admit. Every container in my compose file still has a hardcoded IP address, which is not how you’re supposed to do it, since Docker will resolve container names for you on a user-defined network. It’s like that because I couldn’t get it working reliably, pinned the addresses so I could move on, and never went back. I set most of this up before ChatGPT existed, so debugging meant pasting error strings into Google and reading Stack Overflow answers from 2016.

Running headless was a learning curve. I set the Pi up with no desktop to keep the OS light, which meant everything happened over SSH on the command line. If you aren’t already comfortable in a terminal that’s a real adjustment, though it’s also exactly why the learning stuck.

An SD card died and took everything with it. Cheap flash storage does not enjoy being written to continuously for months. I lost a working Home Assistant configuration and rebuilt it from memory, which is the single most annoying afternoon in this entire story. Duplicati appears in the table above because of that afternoon. Set up backups before you need them, not after.

The part I didn’t expect #

Once the whole thing was finished, sensors and all, I noticed I was getting irritated by it. Turning off a light meant unlocking my phone, opening the Home Assistant app, waiting for it to load, finding the right toggle. Or talking to the speaker and hoping it heard me correctly.

So I bought physical switches and put them on the wall next to most of my lights. You press them and the light goes off. They work by sending a signal to the Home Assistant server, which then turns off the bulb, which is a slightly absurd amount of infrastructure to arrive back at a light switch.

I’ve made peace with it. The switch does the boring 90% of interactions, and the server underneath does the interesting 10% that a switch can’t: the sunrise before my alarm, the notification when the front door opens, the charger cutting out at 85%. It just took me two years and about twenty services to work out which was which.

The verdict from everyone else is fairly consistent. They like the idea of the slow light wakeup, and they think it’s a lot of effort for some lights. Both of those are true.

What’s next #

This was the why. The next few posts are the how:

  • Home Assistant in depth, including exactly how the lights start their sunrise five minutes before my alarm.
  • Ambient lighting with Hyperion and LedFX, and the addressable LED rabbit hole underneath it.
  • Home networking: Tailscale, OpenWRT and Pi-hole, and how they combine to give every device its own rules.
  • Linux, and why I chose EndeavourOS after far too much deliberation.